# frozen_string_literal: true

module Gitlab
  module BackgroundMigration
    # rubocop:disable Style/Documentation
    class PopulateVulnerabilityReads
      include Gitlab::Database::DynamicModelHelpers

      PAUSE_SECONDS = 0.1

      def perform(start_id, end_id, sub_batch_size)
        vulnerability_model.where(id: start_id..end_id).each_batch(of: sub_batch_size) do |sub_batch|
          first, last = sub_batch.pick(Arel.sql('min(id), max(id)'))
          connection.execute(insert_query(first, last))

          sleep PAUSE_SECONDS
        end

        mark_job_as_succeeded(start_id, end_id, sub_batch_size)
      end

      private

      def vulnerability_model
        define_batchable_model('vulnerabilities', connection: connection)
      end

      def connection
        ApplicationRecord.connection
      end

      def insert_query(start_id, end_id)
        <<~SQL
          INSERT INTO vulnerability_reads (
            vulnerability_id,
            project_id,
            scanner_id,
            report_type,
            severity,
            state,
            has_issues,
            resolved_on_default_branch,
            uuid,
            location_image
          )
          SELECT
            vulnerabilities.id,
            vulnerabilities.project_id,
            vulnerability_scanners.id,
            vulnerabilities.report_type,
            vulnerabilities.severity,
            vulnerabilities.state,
            CASE
              WHEN
                vulnerability_issue_links.vulnerability_id IS NOT NULL
              THEN
                true
              ELSE
                false
            END
            has_issues,
            vulnerabilities.resolved_on_default_branch,
            vulnerability_occurrences.uuid::uuid,
            vulnerability_occurrences.location ->> 'image'
          FROM
            vulnerabilities
          INNER JOIN vulnerability_occurrences ON vulnerability_occurrences.vulnerability_id = vulnerabilities.id
          INNER JOIN vulnerability_scanners ON vulnerability_scanners.id = vulnerability_occurrences.scanner_id
          LEFT JOIN vulnerability_issue_links ON vulnerability_issue_links.vulnerability_id = vulnerabilities.id
          WHERE vulnerabilities.id BETWEEN #{start_id} AND #{end_id}
          ON CONFLICT(vulnerability_id) DO NOTHING;
        SQL
      end

      def mark_job_as_succeeded(*arguments)
        Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
          self.class.name.demodulize,
          arguments
        )
      end
    end
    # rubocop:enable Style/Documentation
  end
end
